﻿
// DuilibHelperDlg.cpp: 实现文件
//

#include "stdafx.h"
#include "DuilibHelper.h"
#include "DuilibHelperDlg.h"
#include "afxdialogex.h"
#include "XmlDesignerDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

namespace
{

}


// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialogEx
{
public:
  CAboutDlg();

  // 对话框数据
#ifdef AFX_DESIGN_TIME
  enum { IDD = IDD_ABOUTBOX };
#endif

protected:
  virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
  DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
  CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CDuilibHelperDlg 对话框



CDuilibHelperDlg::CDuilibHelperDlg(CWnd* pParent /*=nullptr*/)
  : CDialogEx(IDD_DUILIBHELPER_DIALOG, pParent)
{
  m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CDuilibHelperDlg::DoDataExchange(CDataExchange* pDX)
{
  CDialogEx::DoDataExchange(pDX);
  DDX_Control(pDX, IDC_LIST_ATTR_NAME, name_list);
  DDX_Control(pDX, IDC_LIST_ATTR_DESC, desc_list);
}

BEGIN_MESSAGE_MAP(CDuilibHelperDlg, CDialogEx)
  ON_WM_SYSCOMMAND()
  ON_WM_PAINT()
  ON_WM_QUERYDRAGICON()
  ON_BN_CLICKED(IDC_BUTTON_NEW, &CDuilibHelperDlg::OnBnClickedButtonNew)
  ON_BN_CLICKED(IDC_BUTTON_OPEN, &CDuilibHelperDlg::OnBnClickedButtonOpen)
  ON_LBN_SELCHANGE(IDC_LIST_ATTR_NAME, &CDuilibHelperDlg::OnAttrNameListSelChanged)
  ON_NOTIFY(NM_SETFOCUS, IDC_LIST_ATTR_DESC, &CDuilibHelperDlg::OnPropertyListSetFocus)
  ON_NOTIFY(NM_KILLFOCUS, IDC_LIST_ATTR_DESC, &CDuilibHelperDlg::OnPropertyListKillFocus)
END_MESSAGE_MAP()


// CDuilibHelperDlg 消息处理程序

BOOL CDuilibHelperDlg::OnInitDialog()
{
  CDialogEx::OnInitDialog();

  // 将“关于...”菜单项添加到系统菜单中。

  // IDM_ABOUTBOX 必须在系统命令范围内。
  ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  ASSERT(IDM_ABOUTBOX < 0xF000);

  CMenu* pSysMenu = GetSystemMenu(FALSE);
  if (pSysMenu != nullptr)
  {
    BOOL bNameValid;
    CString strAboutMenu;
    bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
    ASSERT(bNameValid);
    if (!strAboutMenu.IsEmpty())
    {
      pSysMenu->AppendMenu(MF_SEPARATOR);
      pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
    }
  }

  // 设置此对话框的图标。  当应用程序主窗口不是对话框时，框架将自动
  //  执行此操作
  SetIcon(m_hIcon, TRUE);			// 设置大图标
  SetIcon(m_hIcon, FALSE);		// 设置小图标

  LoadAttrFile();
  SetupUI();

  return TRUE;  // 除非将焦点设置到控件，否则返回 TRUE
}

void CDuilibHelperDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
  if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  {
    CAboutDlg dlgAbout;
    dlgAbout.DoModal();
  } else
  {
    CDialogEx::OnSysCommand(nID, lParam);
  }
}

// 如果向对话框添加最小化按钮，则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序，
//  这将由框架自动完成。

void CDuilibHelperDlg::OnPaint()
{
  if (IsIconic())
  {
    CPaintDC dc(this); // 用于绘制的设备上下文

    SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

    // 使图标在工作区矩形中居中
    int cxIcon = GetSystemMetrics(SM_CXICON);
    int cyIcon = GetSystemMetrics(SM_CYICON);
    CRect rect;
    GetClientRect(&rect);
    int x = (rect.Width() - cxIcon + 1) / 2;
    int y = (rect.Height() - cyIcon + 1) / 2;

    // 绘制图标
    dc.DrawIcon(x, y, m_hIcon);
  } else
  {
    CDialogEx::OnPaint();
  }
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CDuilibHelperDlg::OnQueryDragIcon()
{
  return static_cast<HCURSOR>(m_hIcon);
}



void CDuilibHelperDlg::SetupUI()
{
  DWORD dwStyle = desc_list.GetExtendedStyle();
  dwStyle |= LVS_EX_SINGLEROW | LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT;
  desc_list.SetExtendedStyle(dwStyle);
  RECT rec;
  desc_list.GetClientRect(&rec);
  desc_list.InsertColumn(0, _T("继承"), LVCFMT_LEFT, 100);
  desc_list.InsertColumn(1, _T("属性名"), LVCFMT_LEFT, 90);
  desc_list.InsertColumn(2, _T("类型"), LVCFMT_LEFT, 100);
  desc_list.InsertColumn(3, _T("默认值"), LVCFMT_LEFT, 100);
  desc_list.InsertColumn(4, _T("备注"), LVCFMT_LEFT, rec.right - rec.left);


  //填充内容
  for (auto element : GLOBAL()->controller_attr_mp_) {
    name_list.AddString(element.first.c_str());
  }
}

void CDuilibHelperDlg::LoadAttrFile()
{
    WCHAR module_path[MAX_PATH]{};
    ::GetModuleFileName(NULL, module_path, MAX_PATH);
    if (!GLOBAL()->Init(fs::canonical(L"属性列表.xml", fs::path{ module_path }.parent_path()).c_str())) {
    ::MessageBox(NULL, L"获取属性列表内容出错", L"error", MB_OK);
    exit(-1);
  }
}

void CDuilibHelperDlg::OnBnClickedButtonNew()
{
  XmlDesignerDlg* dlg = new XmlDesignerDlg(L"");
  dlg->Create(IDD_DIALOG_MAKE_XML, this);
  dlg->on_attr_value_list_sel_ += std::bind(&CDuilibHelperDlg::SetSel, this, std::placeholders::_1, std::placeholders::_2);
  dlg->ShowWindow(SW_SHOW);
}


void CDuilibHelperDlg::OnBnClickedButtonOpen()
{
  CFileDialog openFileDlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_READONLY, _T("文件 (*.xml)|*.xml||"), NULL);
  if (openFileDlg.DoModal() == IDOK) {
    CString  filePath = openFileDlg.GetPathName();
    xml_document doc;
    xml_parse_result ret = doc.load_file(filePath.GetBuffer());
    if (ret.status != status_ok) { AfxMessageBox(_T("加载xml文件出错")); return; }
    xml_node node_window = doc.child(L"Window");
    if (node_window.empty()) { AfxMessageBox(_T("不是有效duilib xml文件")); return; }

    XmlDesignerDlg* dlg = new XmlDesignerDlg(filePath);
    dlg->on_attr_value_list_sel_ += std::bind(&CDuilibHelperDlg::SetSel, this, std::placeholders::_1, std::placeholders::_2);
    dlg->Create(IDD_DIALOG_MAKE_XML, this);
    dlg->ShowWindow(SW_SHOW);
  }
}


void CDuilibHelperDlg::OnAttrNameListSelChanged()
{
  CString strName;
  int index = name_list.GetCurSel();
  name_list.GetText(index, strName);
  desc_list.DeleteAllItems();
  char buf[24]{};
  for (auto attr : GLOBAL()->controller_attr_mp_[strName.GetBuffer()]) {
    desc_list.InsertItem(0, attr.second.inherit_.c_str());
    desc_list.SetItemText(0, 1, attr.first.c_str());
    desc_list.SetItemText(0, 2, attr.second.type_.c_str());
    desc_list.SetItemText(0, 3, attr.second.default_.c_str());
    desc_list.SetItemText(0, 4, attr.second.comment_.c_str());
  }
}

bool CDuilibHelperDlg::SetSel(wstring ctrl_name, wstring attr_name)
{
  CString ctr_name_;
  int i = 0;
  for (; i < name_list.GetCount(); i++) {
    name_list.GetText(i, ctr_name_);
    if (ctr_name_.GetBuffer() == ctrl_name)
      break;
  }
  name_list.SetCurSel(i);
  OnAttrNameListSelChanged();
  for (i = 0; i < desc_list.GetItemCount(); i++) {
    if (attr_name.c_str() == desc_list.GetItemText(i, 1)) {
      nSelItem = i;
      desc_list.SetItemState(i, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED | LVIF_STATE);
      desc_list.EnsureVisible(i, TRUE);
      desc_list.SetFocus();
      break;
    }
  }

  return true;
}

void CDuilibHelperDlg::OnPropertyListSetFocus(NMHDR* pNMHDR, LRESULT* pResult)
{
  nSelItem = desc_list.GetSelectionMark();
  desc_list.SetItemState(nSelItem, LVIS_DROPHILITED, LVIS_DROPHILITED);
  *pResult = 0;
}

void CDuilibHelperDlg::OnPropertyListKillFocus(NMHDR* pNMHDR, LRESULT* pResult)
{
  //desc_list.SetItemState(nSelItem, FALSE, LVIF_STATE);
  *pResult = 0;
}
